//@author A0081058H
package net.mysoc.w111j.ui.main;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.Node;

/**
 * The model for the main application. Contains the currently displayed item. Change the scene by changing the
 * {@code MainModel} contentProperty -- call setContent(Node content).
 */
public class MainModel {
    private final ObjectProperty<Node> content;
    private final StringProperty budgetProperty;
    private final StringProperty expenditureProperty;
    private final StringProperty statusProperty;
    private final BooleanProperty undoButtonDisableProperty;
    private final StringProperty commandLineProperty;
    private final StringProperty searchFieldProperty;

    /**
     * Default constructor. Creates a {@code SimpleObjectProperty} binding a {@code Node}.
     */
    public MainModel() {
        this.content = new SimpleObjectProperty<>();
        this.budgetProperty = new SimpleStringProperty();
        this.expenditureProperty = new SimpleStringProperty();
        this.statusProperty = new SimpleStringProperty();
        this.undoButtonDisableProperty = new SimpleBooleanProperty();
        this.commandLineProperty = new SimpleStringProperty();
        this.searchFieldProperty = new SimpleStringProperty();
    }

    /**
     * Returns the binding containing the currently displayed node.
     *
     * @return the {@code ObjectProperty} binding.
     */
    public ObjectProperty<Node> contentProperty() {
        return this.content;
    }

    /**
     * Returns the {@code Node} contained inside the {@code ObjectProperty} wrapper.
     *
     * @return the {@code Node} contained inside the {@code ObjectProperty} wrapper.
     */
    public Node getContent() {
        return this.content.get();
    }

    /**
     * Sets the {@code Node} to be contained inside this {@code MainModel}'s {@code ObjectProperty}.
     *
     * @param content the {@code Node} to be contained inside this {@code MainModel}'s {@code ObjectProperty}.
     */
    public void setContent(Node content) {
        this.content.set(content);
    }

    /**
     * Returns the {@code StringProperty} containing the budget.
     *
     * @return the {@code StringProperty} containing the budget.
     */
    public StringProperty budgetProperty() {
        return this.budgetProperty;
    }

    /**
     * Returns the {@code String} of the budget stored in its {@code StringProperty}.
     *
     * @return the {@code String} of the budget stored in its {@code StringProperty}.
     */
    public String getBudget() {
        return this.budgetProperty.get();
    }

    /**
     * Sets the budget to be displayed in the view.
     *
     * @param budget the budget to be displayed in the view.
     */
    public void setBudget(String budget) {
        this.budgetProperty.set(budget);
    }

    /**
     * Sets the expenditure to be displayed in the view.
     *
     * @param expenditure the expenditure to be displayed in the view.
     */
    public void setExpenditure(String expenditure) {
        this.expenditureProperty.set(expenditure);
    }

    /**
     * Returns the {@code StringProperty} containing the expenditure.
     *
     * @return the {@code StringProperty} containing the expenditure.
     */
    public StringProperty expenditureProperty() {
        return this.expenditureProperty;
    }

    /**
     * Returns the {@code String} of the expenditure stored in its {@code StringProperty}.
     *
     * @return the {@code String} of the expenditure stored in its {@code StringProperty}.
     */
    public String getExpenditure() {
        return this.expenditureProperty.get();
    }

    /**
     * Sets the status to be displayed in the view.
     *
     * @param status the status to be displayed in the view.
     */
    public void setStatus(String status) {
        this.statusProperty.set(status);
    }

    /**
     * Returns the {@code StringProperty} containing the status.
     *
     * @return the {@code StringProperty} containing the status.
     */
    public StringProperty statusProperty() {
        return this.statusProperty;
    }

    /**
     * Returns the {@code String} of the status stored in its {@code StringProperty}.
     *
     * @return the {@code String} of the status content stored in its {@code StringProperty}.
     */
    public String getStatus() {
        return this.statusProperty.get();
    }

    /**
     * Sets the command line to be displayed in the view.
     *
     * @param command the command to be displayed in the view.
     */
    public void setCommandLine(String command) {
        this.commandLineProperty.set(command);
    }

    /**
     * Returns the {@code StringProperty} containing the command line content.
     *
     * @return the {@code StringProperty} containing the command line content.
     */
    public StringProperty commandLineProperty() {
        return this.commandLineProperty;
    }

    /**
     * Returns the {@code String} of the command line stored in its {@code StringProperty}.
     *
     * @return the {@code String} of the command line stored in its {@code StringProperty}.
     */
    public String getCommandLine() {
        return this.commandLineProperty.get();
    }

    /**
     * Sets the search field property content.
     *
     * @param query set the search field to this value.
     */
    public void setSearchField(String query) {
        this.searchFieldProperty.set(query);
    }

    /**
     * Returns the {@code StringProperty} containing the search field content.
     *
     * @return the {@code StringProperty} containing the search field content.
     */
    public StringProperty searchFieldProperty() {
        return this.searchFieldProperty;
    }

    /**
     * Returns the {@code String} of the search field stored in its {@code StringProperty}.
     *
     * @return the {@code String} of the search field stored in its {@code StringProperty}.
     */
    public String getSearchField() {
        return this.searchFieldProperty.get();
    }

    /**
     * Sets whether the undo button should be disabled.
     *
     * @param toDisable whether the undo button should be disabled.
     */
    public void setUndoButtonDisable(boolean toDisable) {
        this.undoButtonDisableProperty.set(toDisable);
    }

    /**
     * Gets the {@code BooleanProperty} controlling whether the undo button should be disabled.
     *
     * @return the {@code BooleanProperty} controlling whether the undo button should be disabled.
     */
    public BooleanProperty undoButtonDisableProperty() {
        return this.undoButtonDisableProperty;
    }

    /**
     * States whether the undo button is currently disabled.
     *
     * @return whether the undo button is currently disabled.
     */
    public boolean isUndoButtonDisabled() {
        return this.undoButtonDisableProperty.get();
    }
}
